package com.kexio.security.service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

import com.kexio.security.domain.LoginSession;

/**
 * 登录会话数据访问接口
 * 
 * @author kexio
 */
public interface LoginSessionRepository {

    /**
     * 保存登录会话
     * @param session 会话实体
     * @return 保存后的会话实体
     */
    LoginSession save(LoginSession session);

    /**
     * 根据ID查找会话
     * @param id 会话ID
     * @return 会话实体
     */
    Optional<LoginSession> findById(Long id);

    /**
     * 根据会话ID查找会话
     * @param sessionId 会话ID
     * @return 会话实体
     */
    Optional<LoginSession> findBySessionId(String sessionId);

    /**
     * 根据访问令牌查找会话
     * @param accessToken 访问令牌
     * @return 会话实体
     */
    Optional<LoginSession> findByAccessToken(String accessToken);

    /**
     * 根据刷新令牌查找会话
     * @param refreshToken 刷新令牌
     * @return 会话实体
     */
    Optional<LoginSession> findByRefreshToken(String refreshToken);

    /**
     * 根据用户ID查找活跃会话
     * @param userId 用户ID
     * @return 会话列表
     */
    List<LoginSession> findActiveByUserId(Long userId);

    /**
     * 根据用户ID和设备类型查找会话
     * @param userId 用户ID
     * @param deviceType 设备类型
     * @return 会话列表
     */
    List<LoginSession> findByUserIdAndDeviceType(Long userId, Integer deviceType);

    /**
     * 根据用户ID查找所有会话
     * @param userId 用户ID
     * @return 会话列表
     */
    List<LoginSession> findByUserId(Long userId);

    /**
     * 更新会话状态
     * @param sessionId 会话ID
     * @param status 状态
     * @return 更新记录数
     */
    int updateStatus(String sessionId, Integer status);

    /**
     * 更新会话最后活跃时间
     * @param sessionId 会话ID
     * @param lastActiveTime 最后活跃时间
     * @return 更新记录数
     */
    int updateLastActiveTime(String sessionId, LocalDateTime lastActiveTime);

    /**
     * 刷新访问令牌
     * @param sessionId 会话ID
     * @param newAccessToken 新访问令牌
     * @param newRefreshToken 新刷新令牌
     * @param expiresAt 过期时间
     * @return 更新记录数
     */
    int refreshToken(String sessionId, String newAccessToken, String newRefreshToken, LocalDateTime expiresAt);

    /**
     * 根据用户ID注销所有会话
     * @param userId 用户ID
     * @return 更新记录数
     */
    int logoutByUserId(Long userId);

    /**
     * 注销会话
     * @param sessionId 会话ID
     * @return 更新记录数
     */
    int logout(String sessionId);

    /**
     * 删除过期会话
     * @param beforeTime 过期时间
     * @return 删除记录数
     */
    int deleteExpiredSessions(LocalDateTime beforeTime);

    /**
     * 删除用户的历史会话
     * @param userId 用户ID
     * @param keepCount 保留数量
     * @return 删除记录数
     */
    int deleteOldSessions(Long userId, int keepCount);

    /**
     * 统计用户活跃会话数
     * @param userId 用户ID
     * @return 活跃会话数
     */
    long countActiveByUserId(Long userId);
}
